Skip to main content
PVAC-HFHE performs all arithmetic operations in a 127-bit prime field F_p where p = 2^127 - 1 (a Mersenne prime).

The prime field F_p

Field definition

The field is defined by the prime:
This is the largest Mersenne prime that fits in 127 bits.
Using a Mersenne prime enables efficient modular reduction using bit shifts and additions instead of expensive division.

Field elements

Field elements are represented as 128-bit integers with the top bit always zero:
From include/pvac/core/field.hpp:17-20:
The hi field uses only 63 bits. Values are stored in the range [0, p-1].

Field operations

Addition

Addition with modular reduction:
From include/pvac/core/field.hpp:50-56. Steps:
  1. Add low words with carry
  2. Add high words with propagated carry
  3. Reduce modulo p using fp_from_words

Subtraction

Subtraction via negation:
Negation computes p - a:
From include/pvac/core/field.hpp:58-67.

Multiplication

Multiplication uses 128×128 → 256-bit widening multiplication:
From include/pvac/core/field.hpp:209-213. Implementation:
  • Uses platform-specific optimizations (x86 assembly, MSVC intrinsics, or portable 128-bit)
  • Computes full 256-bit product
  • Reduces modulo 2^127 - 1 efficiently
The x86 assembly version uses native mulq instructions for maximum performance.

Reduction modulo p

The reduction algorithm exploits the Mersenne prime structure:
From include/pvac/core/field.hpp:179-207. Key insight: Since 2^127 ≡ 1 (mod p), we can reduce by adding the high bits to the low bits.

Inversion

Inversion uses Fermat’s Little Theorem: a^(p-1) ≡ 1 (mod p), so a^(-1) = a^(p-2).
The constant-time implementation uses a windowed exponentiation algorithm:
From include/pvac/core/field.hpp:229-269.
Inversion is constant-time to prevent timing side-channels, but it’s expensive (~100× slower than multiplication).

Why this field?

Advantages of F_(2^127 - 1)

  1. Mersenne prime: Fast reduction using bit operations
  2. Large enough: 127 bits provides ample space for computations
  3. Multiplicative group: p-1 = 2^127 - 2 is divisible by many small factors
  4. No NTT constraints: Unlike RLWE schemes, no need for NTT-friendly primes

Multiplicative group structure

The multiplicative group has order p - 1 = 2^127 - 2. Key generation requires finding a generator g of a subgroup of order B = 337: From include/pvac/core/types.hpp:40:
The parameter B is chosen so that B | (p-1), enabling efficient subgroup operations. The value 337 is a prime that divides 2^127 - 2.
The public key stores precomputed powers:
This enables fast lookups during encryption and homomorphic operations.

Vector operations

For batching (multi-slot encryption), operations extend element-wise:
From include/pvac/ops/encrypt.hpp:150-154.

Performance

Field operation timings on modern x86-64 CPUs:
For best performance, compile with -march=native to enable platform-specific optimizations.

Code example

Next steps

Encryption scheme

Learn how field elements are encrypted

Homomorphic operations

Understand operations on encrypted data